`include "aes_core_h.v"

module aes_core
(
  //OUTPUTS
  output [`COL_SIZE - 1:0] bus_rd,
  output interrupt,
  output busy_n,
  //INPUTS
  input [`COL_SIZE - 1:0] bus_wr,
  input write_en,
  input read_en,
  input [3:0] addr,
  input clk,
  input rst_n
);

wire [`COUNT_SIZE - 1:0] rd_count;
wire [   `COL_NUM - 1:0] col_en;
wire [   `KEY_NUM - 1:0] key_en, key_en_top;
wire [1:0] mode;
//wire [1:0] bus_src;
wire [2:0] sbox_src;
wire [1:0] rk_src;
wire [1:0] rkkey_src;
wire [1:0] col_src;
wire start;
wire config_en;
wire config_src;
wire key_src;
wire rd_count_clear;
wire rd_count_en;
wire start_set;
wire int_set;
wire enc_dec;
wire key_gen;

wire [1:0] rkkey_src_top;
wire [2:0] sbox_src_top;
//wire [1:0] bus_src_top;
wire [1:0] bus_reg_src;
wire [3:0] col_addr, col_en_top;
wire [3:0] key_addr;
wire       config_addr, config_en_top;


//Address Decoder - read operation
assign rkkey_src_top = (addr[1:0] & {2{busy_n}}) | rkkey_src;
assign sbox_src_top  = ({1'b0,addr[1:0]} & {3{busy_n}}) | sbox_src;
assign bus_reg_src   =  addr[3:2];

//Address Decoder - write operation
assign {config_addr, key_addr, col_addr} = 9'b0_0000_0001 << addr;
//assign {col_addr, key_addr, config_addr} = 9'b1000_0000_0 >> addr;
assign col_en_top    = (   col_addr & {4{busy_n & write_en}}) | col_en;
assign key_en_top    = (   key_addr & {4{busy_n & write_en}});
assign config_en_top = (config_addr &    busy_n & write_en  ) | config_en;

aes_core_datapath DATAPATH
(
  .bus_rd         ( bus_rd         ),
  .rd_count       ( rd_count       ),  
  .start          ( start          ),                        
  .interrupt      ( interrupt      ),                   
  .mode           ( mode           ),                    
  .bus_wr         ( bus_wr         ),          
  .col_en         ( col_en_top     ),       
  .key_en         ( key_en         ),      
  .key_bus_en     ( key_en_top     ),
  .config_en      ( config_en_top  ),                    
  .config_src     ( config_src     ),                    
  .col_src        ( col_src        ),                         
  .key_src        ( key_src        ),                                   
  .sbox_src       ( sbox_src_top   ),              
  .rk_src         ( rk_src         ),                
  .rkkey_src      ( rkkey_src_top  ),                
  .rd_count_clear ( rd_count_clear ),                 
  .rd_count_en    ( rd_count_en    ),                    
  .start_set      ( start_set      ),                      
  .int_set        ( int_set        ),                        
  .enc_dec        ( enc_dec        ),                       
  .bus_reg_src    ( bus_reg_src    ),
  .key_gen        ( key_gen        ),
  .bus_read_en    ( read_en        ),           
  .clk            ( clk            ),
  .rst_n          ( rst_n          )
);

aes_core_control_unit CONTROL_UNIT
(  
  .col_en         ( col_en         ),       
  .key_en         ( key_en         ),     
  .config_en      ( config_en      ),                    
  .config_src     ( config_src     ),                    
  .col_src        ( col_src        ),                        
  .key_src        ( key_src        ),                                        
  .sbox_src       ( sbox_src       ),                 
  .rk_src         ( rk_src         ),                   
  .rkkey_src      ( rkkey_src      ),                
  .rd_count_clear ( rd_count_clear ),                 
  .rd_count_en    ( rd_count_en    ),                    
  .start_set      ( start_set      ),                    
  .int_set        ( int_set        ),                      
  .busy_n         ( busy_n         ),                                     
  .rd_count       ( rd_count       ),  
  .start          ( start          ),                
  .mode           ( mode           ),                 
  .enc_dec        ( enc_dec        ), 
  .key_gen        ( key_gen        ),                  
  .clk            ( clk            ),   
  .rst_n          ( rst_n          )
);

endmodule
